
#include "gtest/gtest.h"
#include "Cent.h"
#include "Dollor.h"
#include "Operation.h"

struct UsdEqTest : testing::Test
{
	bool checkEq(const Usd& left, const Usd& right)
	{
		return TRUE == eq(&left, &right);
	}
};

TEST_F(UsdEqTest, test_1_dollor_should_eq_1_dollor)
{
	ASSERT_TRUE(checkEq({1, Dollar}, {1, Dollar}));
}

TEST_F(UsdEqTest, test_1_dollor_should_not_eq_2_dollor)
{
	ASSERT_TRUE(!checkEq({1, Dollar}, {2, Dollar}));
}

struct UsdArithmeticTest : UsdEqTest
{
	Usd afterPlus(const Usd& usd1, const Usd& usd2)
	{
		return plus(&usd1, &usd2);
	}

	Usd afterMinus(const Usd& usd1, const Usd& usd2)
	{
		return minus(&usd1, &usd2);
	}
};

TEST_F(UsdArithmeticTest, test_1_dollor_plus_1_dollor_should_eq_2_dollor)
{
    ASSERT_TRUE(checkEq(afterPlus({1, Dollar}, {1, Dollar})
						, {2, Dollar}));
}

TEST_F(UsdArithmeticTest, test_3_dollor_minus_1_dollor_should_not_eq_1_dollor)
{
    ASSERT_TRUE(!checkEq(afterMinus({3, Dollar}, {1, Dollar})
						, {1, Dollar}));
}

TEST_F(UsdEqTest, test_1_dollor_should_eq_100_cent)
{
    ASSERT_TRUE(checkEq({1, Dollar}, {100, Cent}));
}

TEST_F(UsdEqTest, test_1_dollor_should_not_eq_200_cent)
{
    ASSERT_TRUE(!checkEq({1, Dollar}, {200, Cent}));
}

TEST_F(UsdArithmeticTest, test_1_dollor_plus_100_cent_should_eq_2_dollor)
{
	ASSERT_TRUE(checkEq(afterPlus({1, Dollar}, {100, Cent})
						,{2, Dollar}));
}

TEST_F(UsdArithmeticTest, test_2_dollor_minus_100_cent_should_not_eq_2_dollor)
{
	ASSERT_TRUE(!checkEq(afterMinus({2, Dollar}, {100, Cent})
						, {2, Dollar}));
}

struct UsdPrintTest : testing::Test
{

	template<int N>
	bool isEq(const char* rhs, const char (&target)[N])
	{
		for(int i = 0; i< N ; ++i)
		{
			if(rhs[i] != target[i]) return false;
		}
		return true;
	}
	
	char* getNormaltOutput(const Usd& usd)
	{
		noramlPrint(&usd, output);
		return output;
	}

	char* getCascadeOutput(const Usd& usd)
	{
		cascadePrint(&usd, output);
		return output;
	}
	
private:
	char output[1000];

};

TEST_F(UsdPrintTest, should_normal_print_dollor_right)
{
	ASSERT_TRUE(isEq(getNormaltOutput({2, Dollar}), "$2"));
}

TEST_F(UsdPrintTest, should_normal_print_cent_right)
{
	ASSERT_TRUE(isEq(getNormaltOutput({2, Cent}), "2¢"));
}

TEST_F(UsdPrintTest, should_cascade_print_dollor_right)
{
	
	ASSERT_TRUE(isEq(getCascadeOutput({532, Dollar}), "5*$100, 1*$20, 1*$10, 1*$2"));
}

TEST_F(UsdPrintTest, should_cascade_print_cent_right)
{
	ASSERT_TRUE(isEq(getCascadeOutput({1030, Cent}), "1*$10, 1*25¢, 1*5¢"));
}

